#include "RedisResult.h"

#include <stdexcept>

using namespace std;
using namespace CwRedis;

RedisResult::RedisResult(redisReply *reply, bool deleteable) {
    if (deleteable) {
        reply_.reset(reply, [](redisReply *&reply) {
            if (reply != nullptr) {
                freeReplyObject(reply);
                reply = nullptr;
            }
        });
    } else {
        reply_.reset(reply, [](redisReply *&reply) {});
    }
}

bool RedisResult::isError() const {
    if (reply_ == nullptr || reply_->type == REDIS_REPLY_ERROR) {
        return true;
    }
    return false;
}

string RedisResult::getError() const {
    if (reply_ == nullptr) {
        throw runtime_error("empty ptr redis reply");
    }
    return reply_->str;
}

std::string RedisResult::toString() const {
    if (reply_ == nullptr) {
        throw runtime_error("empty ptr redis reply");
    }
    if (reply_->type != REDIS_REPLY_STRING) {
        throw runtime_error("illegal type conversions to string");
    }
    return reply_->str;
}

long long RedisResult::toInteger() const {
    if (reply_ == nullptr) {
        throw runtime_error("empty ptr redis reply");
    }
    if (reply_->type != REDIS_REPLY_INTEGER) {
        throw runtime_error("illegal type conversions to integer");
    }
    return reply_->integer;
}

bool RedisResult::isNil() const {
    if (reply_ == nullptr) {
        throw runtime_error("empty ptr redis reply");
    }
    if (reply_->type != REDIS_REPLY_NIL) {
        throw runtime_error("illegal type conversions to nil");
    }
    return reply_->type == REDIS_REPLY_NIL;
}

vector<RedisResult> RedisResult::toArray() const {
    if (reply_ == nullptr) {
        throw runtime_error("empty ptr redis reply");
    }
    if (reply_->type != REDIS_REPLY_ARRAY) {
        throw logic_error("illegal type conversions to array");
    }
    vector<RedisResult> ret;
    for (size_t i = 0; i < reply_->elements; ++i) {
        ret.push_back(RedisResult((redisReply *) reply_->element[i], false));
    }
    return ret;
}

int RedisResult::getType() const {
    if (reply_ == nullptr) {
        throw runtime_error("empty ptr redis reply");
    }
    return reply_->type;
}